/**      
 * @file		polymorphicBehavior.cpp
 * @description		This redefines the notPolymorphic behavior using
 *			dynamic binding and polymorphism
 * @course		CSCI 123 Section 00000
 * @assignment 
 * @date		mm/dd/yyyy
 * @author		Brad Rippe (00000000) brippe@fullcoll.edu
 * @version		1.0
 */
#include <iostream>
using namespace std;

/**
 * Simple Base Class Example
 * @author: Brad Rippe (brippe@fullcoll.edu)
 */
class BaseClass {
public:

	/**
	 * Returns a string representation of the object
	 * NOTE THE KEYWORD VIRTUAL
	 * @return the string representation
	 */
	virtual string toString() {
		return "Base Class";
	}
};


/**
 * Simple Derived class
 * What's the relationship between BaseClass and Derived class?
 * @author: Brad Rippe (brippe@fullcoll.edu)
 */
class DerivedClass1: public BaseClass {

	/**
	 * Returns a string representation of the object
	 * Is this overloading or redefining the function?
	 * @return the string representation
	 */
	string toString() {
		return "DerivedClass 1";
	}
};

/**
 * Simple Derived from a Derived class
 * This class makes the BaseClass a grandparent
 * @author: Brad Rippe (brippe@fullcoll.edu)
 */
class DerivedClass2: public DerivedClass1 {

	/**
	 * Returns a string representation of the object
	 * Is this overloading or redefining the function?
	 * @return the string representation
	 */
	string toString() {
		return "DerivedClass 2";
	}
};

/**
 * Outputs the toString result to the screen
 * @param aClass the class to output the result of toString
 */
void displayObject(BaseClass *aClass) {
	// what's the difference between this call and the call
	// in notPolymorphism?
	// What do you need to make polymorphism work? (Two Things)
	cout << aClass->toString().data() << endl;
}

/**
 * @return zero if the application executes successfully
 */
int main() {
	
	// What's different here from the last sample?
	BaseClass *bc = new BaseClass();
	DerivedClass1 *dc1 = new DerivedClass1();
	DerivedClass2 *dc2 = new DerivedClass2();
	
	displayObject(bc);
	displayObject(dc1);
	displayObject(dc2);
	
	// be nice and clean up my mess
	// what happens if I don't?
	delete dc2;
	delete dc1;
	delete bc;
	return 0;
}
